package com.imooc.myapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

public class FlagBitmapMeshView extends View {

    /* Draw the bitmap through the mesh, where mesh vertices are evenly
     * distributed across the bitmap. There are meshWidth+1 vertices across, and
     * meshHeight+1 vertices down. The verts array is accessed in row-major
     * order, so that the first meshWidth+1 vertices are distributed across the
     * top of the bitmap from left to right. A more general version of this
     * method is drawVertices().*/
//    通过网格绘制位图，其中网格顶点均匀分布在位图上。有网格宽度+1个顶点，网格高度+1个顶点。
//    将以行为主的顺序访问涵洞数组，以便第一个网格宽度+1个顶点从左到右分布在位图的顶部。
//    这个方法的一个更通用的版本是drawvertex()。//有道翻译。。。。。。

    //本view要点：
    // 1.获取所有交叉点坐标；
    // 2.每一次刷新中，  横不变，纵正弦相关变化， 绘制得到一个静止的扭曲图象；
    // 3.线程刷新，不断更新纵坐标偏移量k ——>> 得到不断变换的一个个静态的正弦波 ——>>
    // 正弦波改动交叉点坐标，绘制得到一个个静态的扭曲图象；
    // 连续更新，连续规律性地绘制静态扭曲图象，产生特效

    private final int WIDTH = 200;//设置网格宽高
    private final int HEIGHT = 200;
    private int COUNT = (WIDTH + 1) * (HEIGHT + 1);//交叉点数目
    private float[] verts = new float[COUNT * 2];//坐标数组
    private float[] orig = new float[COUNT * 2];

    private Bitmap bitmap;
    private float A;
    private float k = 1;

    public FlagBitmapMeshView(Context context) {
        super(context);
        initView(context);
    }

    public FlagBitmapMeshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public FlagBitmapMeshView(Context context, AttributeSet attrs,
                              int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        setFocusable(true);
        bitmap = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.test2);//解码图片
        float bitmapWidth = bitmap.getWidth();//位图宽
        float bitmapHeight = bitmap.getHeight();//位图高

        //循环存储COUNT个交叉点
        int index = 0;
        for (int y = 0; y <= HEIGHT; y++) {    // 循环（HEIGHT + 1 ）次
            float fy = bitmapHeight * y / HEIGHT; //把位图高分成 HEIGHT 份，从 0 开始逐一叠加
            for (int x = 0; x <= WIDTH; x++) {
                float fx = bitmapWidth * x / WIDTH; //道理同上
                orig[index * 2 + 0] = verts[index * 2 + 0] = fx; //0 2 4 6 。。。
                orig[index * 2 + 1] = verts[index * 2 + 1] = fy + 100;//1 3 5 7 。。。
                index += 1;
            }
        }
        A = 50;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        flagWave();
        k += 0.1F;
        canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT,
                verts, 0, null, 0, null);
        invalidate();

    }

    //每一次draw中，整体所有 y 坐标共同加上一个静止的正弦函数波/值，每一个点加的值又不同，
    // 这取决与i / WIDTH ， 即在2PI中的位置，即对应正弦波上的值

    //每刷新一次通过 k += 0.1F;  刷新正弦函数波/值，整体的y值加上一个新的正弦波，使得图像发生变化
    private void flagWave() {
        for (int j = 0; j <= HEIGHT; j++) {
            for (int i = 0; i <= WIDTH; i++) {
//                verts[(j * (WIDTH + 1) + i) * 2 + 0] += 0;
                float offsetY =
                        (float) Math.sin((float) i / WIDTH * 2 * Math.PI +
                                Math.PI * k);//做正弦变换（ 2xPI + kPI ）//i / WIDTH * 2 * Math.PI使所有点的y坐标构成一个完整的正弦2PI周期
                verts[(j * (WIDTH + 1) + i) * 2 + 1] =
                        orig[(j * WIDTH + i) * 2 + 1] + offsetY * A;//横坐标不变，纵坐标加一个正弦变化值
            }
        }
    }
}